//
// Created by root on 24-7-21.
//

#include "./include/epoll_event_hand.h"
#include "include/get_server_socket.h"
#include "include/hand_error.h"
#include "include/hand_socket_stream.h"
#include "include/response_http.h"
#define MAX_EVENT_NUMS 1024
#define SERVER_IPADDR NULL
#define SERVER_PORT 8888
#define CLIFD_CAN_WRITE 1
#define CLIFD_CANNOT_WRITE 0

static int clientfd_can_write [MAX_EVENT_NUMS]={CLIFD_CANNOT_WRITE};

int do_accept(int list_socket, int epfd) {
    struct sockaddr_in cliaddr;
    bzero(&cliaddr,sizeof(cliaddr));
    socklen_t addrlen = sizeof(struct sockaddr_in);
    int fd = accept(list_socket,(struct sockaddr*)&cliaddr,&addrlen);
    if(fd < 0){
        perror("accept");
        return (-1);
    }
    printf("Accept new client <%s:%d>\n",inet_ntoa(cliaddr.sin_addr),ntohs(cliaddr.sin_port));

    epoll_event_add(epfd,fd,EV_READ);
    return 0;
};

int recv_client(int epfd, struct epoll_event * evs, int i) {
    int fd = evs[i].data.fd;
    char buf[1024*10]={0};
    bzero(buf,sizeof(buf));
    char buffer[1024*10];
    while (1) {
        int offset = readline(fd, buffer, 1024*10);
        if (offset==0) {

            return 0;
        }
        if (buffer[0] == '\r' && buffer[1] == '\n') {
            printf("%-20s\n", "accept head over");
            epoll_event_del(epfd,fd,EV_READ);
            epoll_event_add(epfd,fd,EV_WRITE);
            return 1;
        }
        buffer[offset - 1] = 0;
        printf("%s\n", buffer);
        fflush(stdout);
        bzero(buffer,sizeof(buffer));
    }

};

int epoll_server() {
    int listSocket = get_server_socket(SERVER_PORT,SERVER_IPADDR);
    int epfd = epoll_create(MAX_EVENT_NUMS);
    if (epfd < 0) {
        myerror("epoll");
    }
    if (epoll_event_add(epfd, listSocket,EV_READ)==-1) {
        perror("add listiner event error");
    };
    struct epoll_event evs[MAX_EVENT_NUMS];
    int i = 0;
    // memset(clifds,-1,sizeof(clifds));
    do {
        int n = epoll_wait(epfd, evs,MAX_EVENT_NUMS, 10);
        if (n == 0) {
            // printf("epoll_wait timeout\n");
            continue;
        }
        if (n < 0) {
            perror("epoll_eait");
            if (errno == EAGAIN || errno == EINTR) {
                continue;
            }

        }
        //
        //     //这里实际是一个reactor
        for (i = 0; i < n; ++i) {
            if (evs[i].events == EV_READ) {
                //             //处理监听套接字的数据
                if (evs[i].data.fd == listSocket) {
                    if (do_accept(listSocket, epfd) < 0) {
                        perror("do_accept");
                    }
                } else {
                    //读取客户端的数据
                    if(recv_client(epfd, evs, i)==0) {
                        sprintf(stderr,"Client <%d> close\n",evs[i].data.fd);
                        epoll_event_del(epfd,evs[i].data.fd,EV_READ);
                        close(evs[i].data.fd);
                    };
                }
            }else if (evs[i].events == EV_WRITE) {
                if(sendhtml(evs[i].data.fd,"/root/CLionProjects/webserver/html/google.html","r")==-1) {
                    perror("send error");
                };
                epoll_event_del(epfd,evs[i].data.fd,EV_WRITE);
                close(evs[i].data.fd);
                printf("Client <%d> success close\n",evs[i].data.fd);
            }
        }
    } while (1);

}
